﻿using System;
using System.Windows;
using DSPL.Services;
using DSPL.Contracts;
using DSPL.Common;
using System.Data;
using DSPL.Services.Services;
using DSPL.Contracts.Common;
using DSPL.Contracts.ViewModel;
using DSPL.Contracts.Command;
using DSPL.Finac.Common;
using System.Windows.Input;
using System.Windows.Controls;

namespace DSPL.Finac.ViewModel
{
    public class CostCentreMasterViewModel : BaseViewModel
    {
        private bool isCostCodeFocused;
        private bool isCostNameFocused;
        private Visibility priorCostLevelVisibility;
        private bool isPriorLevelEnabled;
        private bool isPriorLevelFocused;
        private string _priorLevel;
        private DataTable _dtCostDet;
        private DataTable _dtAccounts;
        private ICommand costCodeTextBoxLostFocused;
        private ICommand _selectCheckBoxClicked;
        private bool costCodeTextBoxEnabled;
        private DataRow _selectedAccountRow;
        private ICommand _gridMouseEnter;


        #region Define properties

        public bool IsCostCodeFocused
        {
            get { return isCostCodeFocused; }
            set
            {
                isCostCodeFocused = value;
                this.OnPropertyChanged("IsCostCodeFocused");
            }
        }

        public bool IsCostNameFocused
        {
            get { return isCostNameFocused; }
            set
            {
                isCostNameFocused = value;
                this.OnPropertyChanged("IsCostNameFocused");

            }
        }

        public bool IsPriorLevelFocused
        {
            get { return isPriorLevelFocused; }
            set
            {
                isPriorLevelFocused = value;
                this.OnPropertyChanged("IsPriorLevelFocused");

            }
        }

        public Visibility PriorCostLevelVisibility
        {
            get
            {
                return priorCostLevelVisibility;
            }

            set
            {
                priorCostLevelVisibility = value;
                this.OnPropertyChanged("PriorCostLevelVisibility");
            }
        }


        public string PriorLevel
        {
            get
            {
                return _priorLevel;
            }

            set
            {
                _priorLevel = value;
                this.OnPropertyChanged("PriorLevel");
                SetupNewCostCode();

            }
        }

        public DataTable DtCostDet
        {
            get
            {
                return _dtCostDet;
            }
            set
            {
                _dtCostDet = value;
                this.OnPropertyChanged("DtCostDet");
            }
        }

        public DataTable DtAccounts
        {
            get
            {
                return _dtAccounts;
            }
            set
            {
                _dtAccounts = value;
                this.OnPropertyChanged("DtAccounts");
            }
        }


        public bool CostCodeTextBoxEnabled
        {
            get
            {
                return costCodeTextBoxEnabled;
            }
            set
            {
                costCodeTextBoxEnabled = value;
                this.OnPropertyChanged("CostCodeTextBoxEnabled");
            }

        }

        public bool IsPriorLevelEnabled
        {
            get
            {
                return isPriorLevelEnabled;
            }
            set
            {
                isPriorLevelEnabled = value;
                this.OnPropertyChanged("IsPriorLevelEnabled");
            }
        }

        public DataRow SelectedAccountRow
        {
            get
            {
                return _selectedAccountRow;
            }
            set
            {
                _selectedAccountRow = value;
                this.OnPropertyChanged("SelectedAccountRow");
            }
        }

        #endregion

        #region Define Commands
        public ICommand CostCodeTextBoxLostFocused
        {
            get
            {
                if (this.costCodeTextBoxLostFocused == null)
                {
                    this.costCodeTextBoxLostFocused = new RelayCommand(TextBoxCostCodeLostFocusExecuted);

                }
                return this.costCodeTextBoxLostFocused;
            }
        }

        public ICommand SelectCheckBoxClicked
        {
            get
            {
                if (this._selectCheckBoxClicked == null)
                {
                    this._selectCheckBoxClicked = new RelayCommand(SelectCheckBoxClickedExecuted);
                }
                return this._selectCheckBoxClicked;
            }
        }

        public ICommand GridMouseEnter
        {
            get
            {
                if (this._gridMouseEnter == null)
                    this._gridMouseEnter = new RelayCommand(GridMouseEnterExecuted);
                return this._gridMouseEnter;
            }
            set { _gridMouseEnter = value; }
        }

        #endregion
        
        #region Constructor

        public CostCentreMasterViewModel()
            : base()
        {
            MessageTitle = "Cost Centre Master";
        }

        #endregion
        
        /// <summary>
        /// Validate mandatory data before save
        /// </summary>
        /// <param name="obj"></param>
        protected override void PreDataValidateExecuted(object obj)
        {
            IsCostCodeFocused = false;
            IsCostNameFocused = false;

            var messageService = new MessageService();
            if (string.IsNullOrEmpty(CurrentRow["CostCode"].ToString().Trim()))
            {
                messageService.ShowMessage(MessageText.CostCodeNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCostCodeFocused = true;
                this.IsValid = false;
                return;
            }

            if (string.IsNullOrEmpty(CurrentRow["CostName"].ToString().Trim()))
            {
                messageService.ShowMessage(MessageText.CostNameNotEmpty, MessageTitle, MessageType.InfoOK);
                IsCostNameFocused = true;
                this.IsValid = false;
                return;
            }

            if ((FormMode == Modes.New) && (PriorLevel == null || (PriorLevel.Trim() == String.Empty)))
            {
                messageService.ShowMessage(MessageText.PriorLevelNotEmpty, MessageTitle, MessageType.InfoOK);
                IsPriorLevelFocused = true;
                this.IsValid = false;
                return;
            }

            DataRow[] selectedRows = DtAccounts.Select("Upd=1");

            if (selectedRows.Length == 0)
            {
                var result = messageService.ShowMessage(MessageText.InvalidChartAccounts, MessageTitle, MessageType.QuizYesNo);
                if (result == MessageBoxResult.No)
                {
                    this.IsValid = false;
                    return;
                }
            }

            this.IsValid = true;
        }

        protected override void RefreshExternalDataObjectsExecueted(object obj)
        {

            base.RefreshExternalDataObjectsExecueted(obj);
            GetCostDetails();

            GetCostCentreAccountDetails();
            PriorLevel = string.Empty;

        }

        protected override void EnableDisableSpecificControls()
        {
            base.EnableDisableSpecificControls();

            if (FormMode == Modes.New)
            {
                PriorCostLevelVisibility = Visibility.Visible;
                CostCodeTextBoxEnabled = true;
            }
            else
            {
                PriorCostLevelVisibility = Visibility.Collapsed;
                CostCodeTextBoxEnabled = false;
            }

        }

        private void GetCostDetails()
        {
            var commonService = new MasterReadService();
            DtCostDet = commonService.GetCostDetails();
            if (DtCostDet != null)
            {
                DtCostDet.Columns.Add("dtcCostLevel1");
                DtCostDet.Columns.Add("dtcCostLevel2");
                DtCostDet.Columns.Add("dtcCostLevel3");
                DtCostDet.Columns.Add("dtcCostLevel4");
                DtCostDet.Columns.Add("dtcCostLevel5");
                DtCostDet.Columns.Add("dtcCostLevel6");
                DtCostDet.Columns.Add("dtcCostLevel7");
                DtCostDet.Columns.Add("dtcCostLevel8");
            }

        }

        private void GetCostCentreAccountDetails()
        {
            var commonService = new MasterReadService();
            int costCode;
            if (CurrentRow["CostPk"] == DBNull.Value)
            {
                costCode = 0;
            }
            else
            {
                costCode = Convert.ToInt32(CurrentRow["CostPk"]);
            }

            DtAccounts = commonService.GetCostCentreAccountDetails(FormMode, costCode);

            if ((FormMode == Modes.New) && (CurrentRow["CostCode"] != DBNull.Value))
            {
                string AccountName;
                foreach (DataRow drAccounts in DtAccounts.Rows)
                {
                    AccountName = drAccounts["AccCode"].ToString().Trim().PadRight(8, ' ').Substring(0, 8) + "-" + CurrentRow["CostCode"].ToString().Trim();
                    drAccounts["AccCode"] = AccountName;
                }
            }

            if ((FormMode == Modes.None || FormMode == Modes.Edit) && (CurrentRow["CostCode"] != DBNull.Value))
            {
                string AccountName;
                foreach (DataRow drAccounts in DtAccounts.Rows)
                {
                    if (Convert.ToInt32(drAccounts["Upd"]) == 0)
                    {
                        AccountName = drAccounts["AccCode"].ToString().Trim().PadRight(8, ' ').Substring(0, 8) + "-" + CurrentRow["CostCode"].ToString().Trim();
                        drAccounts["AccCode"] = AccountName;
                    }
                }
            }
        }

        private void TextBoxCostCodeLostFocusExecuted(object obj)
        {
            TextBox costCodeTextBox = (TextBox)obj;
            CostCodeTextBoxEnabled = false;
            IsCostCodeFocused = false;
            if (costCodeTextBox.Text != string.Empty)
            {
                bool isDuplicate = new MasterReadService().IsCostCodeDuplicate(Convert.ToString(CurrentRow["CostCode"]));
                var messageService = new MessageService();
                if (isDuplicate == true)
                {
                    messageService.ShowMessage(MessageText.CostCodeDuplicate, MessageTitle, MessageType.InfoOK);
                    CurrentRow["CostCode"] = string.Empty;
                    this.OnPropertyChanged("CurrentRow");
                    CostCodeTextBoxEnabled = true;
                    IsPriorLevelEnabled = false;
                    IsCostCodeFocused = true;
                    return;

                }
                else
                {
                    CostCodeTextBoxEnabled = false;
                    IsPriorLevelEnabled = true;
                    GetCostCentreAccountDetails();
                }
            }
            else
            {
                if (FormMode == Modes.New && costCodeTextBox.Text == string.Empty)
                    CostCodeTextBoxEnabled = true;
            }

        }

        private void SetupNewCostCode()
        {
            var messageService = new MessageService();
            if (FormMode == Modes.New)
            {
                DataTable dtSelectedPriorCostCode = new MasterReadService().GetCostDetails(PriorLevel);

                if (dtSelectedPriorCostCode.Rows.Count == 0)
                {
                    PriorLevel = string.Empty;
                    IsPriorLevelEnabled = true;
                    messageService.ShowMessage(MessageText.InvalidPriorLevel, MessageTitle, MessageType.InfoOK);
                    IsPriorLevelFocused = true;
                    return;
                }
                if (dtSelectedPriorCostCode.Rows[0]["CostCon"].ToString().Trim() == "Y")
                {
                    CurrentRow["Level1"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["CostPk"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level2"] = CurrentRow["CostPk"];
                    this.OnPropertyChanged("CurrentRow");
                }

                else
                {
                    if (Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level1"]) == 0)
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level1"] = 0;
                    }
                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level2"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level2"] = 0;
                    }
                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level3"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level3"] = 0;
                    }
                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level4"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level4"] = 0;
                    }
                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level5"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level5"] = 0;
                    }
                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level6"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level6"] = 0;
                    }
                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level7"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level7"] = 0;
                    }

                    else if ((Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level8"]) == 0))
                    {
                        dtSelectedPriorCostCode.Rows[0]["Level8"] = 0;
                    }

                    CurrentRow["Level1"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level1"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level2"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level2"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level3"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level3"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level4"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level4"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level5"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level5"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level6"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level6"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level7"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level7"]);
                    this.OnPropertyChanged("CurrentRow");
                    CurrentRow["Level8"] = Convert.ToInt32(dtSelectedPriorCostCode.Rows[0]["Level8"]);
                    this.OnPropertyChanged("CurrentRow");
                }

            }
        }



        protected override void PreDataDelValidationExecuted(object obj)
        {
            var masterReadService = new ReadService();
            DataTable dtSelectedAccounts = new DataTable();
            dtSelectedAccounts = DtAccounts.Select("Upd=1").CopyToDataTable();
            DataView view = new DataView(dtSelectedAccounts);
            DataTable dtSelected = view.ToTable("Selected", false, "AccCode", "AccDesc");

            bool isValid = (bool)masterReadService.CheckValidityAccountCodesDeletion("fGlfAcc", "AccCode", dtSelected);

            if (!isValid)
            {
                this.IsValid = false;
                return;
            }

            var masterDataRetrieve = new MasterReadService();
            var messageService = new MessageService();
            if (masterDataRetrieve.IsCostCodeUsedInOtherLevels(Convert.ToInt32(CurrentRow["CostPk"])))
            {
                messageService.ShowMessage(MessageText.CostCodeAllocated, MessageTitle, MessageType.InfoOK);
                this.IsValid = false;
                return;
            }

            if (CurrentRow["CostCon"].ToString().Trim() == "Y")
            {
                if (DtCostDet.Rows.Count > 0)
                {
                    messageService.ShowMessage(MessageText.ConsolidatedCostCode, MessageTitle, MessageType.InfoOK);
                    this.IsValid = false;
                    return;
                }
            }

            this.IsValid = true;
        }

        protected override void PostDataUpdateExecuted(object obj)
        {
            var commonService = new MasterWriteService();
            var messageService = new MessageService();
            var result = messageService.ShowMessage(MessageText.ChartOfAccountsExists, MessageTitle, MessageType.QuizYesNo);
            if (result == MessageBoxResult.No)
            {
                this.IsValid = false;
                return;
            }
            var sqlTran = this.SqlTran;
            if (!commonService.UpdateCostCentreAccounts(CurrentRow, DtAccounts, ref sqlTran))
            {
                this.IsValid = false;
            }

            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }
        }


        /// <summary>
        /// To build up the insert statements to update related child tables.
        /// </summary>
        /// <param name="writeData"></param>
        /// <returns></returns>
        /// 
        protected override void PostDataInsertExecuted(object obj)
        {
            var commonService = new MasterWriteService();
            var sqlTran = this.SqlTran;

            UpdateMaximumCostLevel();

            if (!commonService.UpdateCostCentreAccounts(CurrentRow, DtAccounts, ref sqlTran))
            {
                this.IsValid = false;
            }

            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }
        }

        /// <summary>
        /// To delete related records from child tables before deletes the master data.
        /// </summary>
        /// <returns></returns>
        protected override void PreDataDeleteExecuted(object obj)
        {
            var commonService = new MasterWriteService();
            var sqlTran = this.SqlTran;
            if (!commonService.DeleteCostCentreAccountDetails(Convert.ToInt32(CurrentRow["CostPk"]), ref sqlTran))
            {
                this.IsValid = false;
            }
            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }
        }

        protected void SelectCheckBoxClickedExecuted(object obj)
        {
            var masterReadService = new ReadService();

            DataTable dtSelectedAccounts = new DataTable();

            DataView view = new DataView(SelectedAccountRow.Table);
            DataTable dtSelected = view.ToTable("Selected", false, "AccCode", "AccDesc");

            bool isValid = (bool)masterReadService.CheckValidityAccountCodesDeletion("fGlfAcc", "AccCode", dtSelected);

            if (!isValid)
            {
                this.IsValid = false;
                DataRow[] selectedRows = DtAccounts.Select("AccCode='" + dtSelected.Rows[0]["AccCode"].ToString().Trim() + "'");
                selectedRows[0]["Upd"] = 1;
                OnPropertyChanged("DtAccounts");
                var messageService = new MessageService();
                messageService.ShowMessage(MessageText.AccountUsed, MessageTitle, MessageType.InfoOK);
                return;
            }

        }

        private void GridMouseEnterExecuted(object obj)
        {
            var drv = obj as DataRowView;
            if (drv != null)
            {
                DataRow dr = drv.Row;
                DataTable dt = DtAccounts;
                string s = dr.Table.Columns[0].ColumnName + " = '" + dr[0].ToString() + "'";
                dt = dt.Select(s).CopyToDataTable();
                SelectedAccountRow = dt.Rows[0];
            }
        }


        private void UpdateMaximumCostLevel()
        {
            string maxFieldieldName = string.Empty;
            var sqlTran = this.SqlTran;
            int costIntKey = Convert.ToInt32(CurrentRow["CostPk"]);
            if (Convert.ToInt32(CurrentRow["Level1"]) == 0)
            {
                CurrentRow["Level1"] = costIntKey;
                maxFieldieldName = "Level1";
            }
            else if ((Convert.ToInt32(CurrentRow["Level2"]) == 0))
            {
                CurrentRow["Level2"] = costIntKey;
                maxFieldieldName = "Level2";
            }
            else if ((Convert.ToInt32(CurrentRow["Level3"]) == 0))
            {
                CurrentRow["Level3"] = costIntKey;
                maxFieldieldName = "Level3";
            }
            else if ((Convert.ToInt32(CurrentRow["Level4"]) == 0))
            {
                CurrentRow["Level4"] = costIntKey;
                maxFieldieldName = "Level4";
            }
            else if ((Convert.ToInt32(CurrentRow["Level5"]) == 0))
            {
                CurrentRow["Level5"] = costIntKey;
                maxFieldieldName = "Level5";
            }
            else if ((Convert.ToInt32(CurrentRow["Level6"]) == 0))
            {
                CurrentRow["Level6"] = costIntKey;
                maxFieldieldName = "Level6";
            }
            else if ((Convert.ToInt32(CurrentRow["Level7"]) == 0))
            {
                CurrentRow["Level7"] = costIntKey;
                maxFieldieldName = "Level7";
            }

            else if ((Convert.ToInt32(CurrentRow["Level8"]) == 0))
            {
                CurrentRow["Level8"] = costIntKey;
                maxFieldieldName = "Level8";
            }

            var masterDataUpdate = new MasterWriteService();
            if (!masterDataUpdate.UpdateCostData(costIntKey, maxFieldieldName, costIntKey, sqlTran))
            {
                this.IsValid = false;
            }
            else
            {
                this.IsValid = true;
                this.SqlTran = sqlTran;
            }


        }

    }
}